package com.drondea.testclient.service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import com.drondea.testclient.model.Model;
import com.drondea.testclient.util.ConfigMemory;
import com.drondea.testclient.util.YamlUtil;

import lombok.extern.slf4j.Slf4j;


/**
 * 配置信息Service
 *
 * @author shd
 */

@Slf4j
public class ConfigService {

    /**
     * 配置信息保存目录
     */
    public static AtomicReference<String> CONFIG_PATH =  new AtomicReference("configuration" + File.separator);

    /**
     * 保存配置信息 先将配置信息保存到缓存中，再保存到文件中 type 配置类型 map 配置信息
     */
    public static int save(String type, Map map) {
        int state = 1;
        try {
            // 保存在缓存中
            ConfigMemory.put(type, map);

            // 保存在文件中
            File file = new File(CONFIG_PATH.get() + type + ".yaml");
            if(!file.exists())
            	file.createNewFile();
            YamlUtil.save(map, file);
        } catch (Exception e) {
            state = 0;
            log.info("错误信息类型：{}，错误信息详情：{}", type, map);
            log.error("保存配置信息错误", e);
        }
        return state;
    }

    /**
     * 更新配置信息 先将配置信息保存到缓存中，再保存到文件中 type 配置类型 map 配置信息
     */
    public static <T> int update(String type, String id, T object) {
        int state = 1;
        try {
            // 更新在缓存中
            ConfigMemory.put(type, id, object);

            // 更新文件信息
            File file = new File(CONFIG_PATH.get() + type + ".yaml");
            Map map = ConfigMemory.get(type, object.getClass());
            YamlUtil.save(map, file);
        } catch (Exception e) {
            state = 0;
            log.info("错误信息类型：{}，错误信息Id：{}", type, id);
            log.error("更新配置信息错误", e);
        }
        return state;
    }

    /**
     * 删除数据 先将配置信息从缓存中删除，再从文件中删除
     */
    public static <T> int delete(String type, String id, Class<T> clazz) {
        int state = 1;
        try {
            // 更新在缓存中
            ConfigMemory.delete(type, id);

            // 更新文件信息
            File file = new File(CONFIG_PATH.get() + type + ".yaml");
            Map map = ConfigMemory.get(type, clazz);
            YamlUtil.save(map, file);
        } catch (Exception e) {
            state = 0;
            log.error("删除配置信息错误", e);
            log.info("错误信息类型：{}，错误信息Id：{}", type, id);
        }
        return state;
    }

    /**
     * 获取一类信息 type 信息类型 clazz 类
     */
    public static <T> Map<String, T> find(String type, Class<T> clazz) {
        return ConfigMemory.get(type, clazz);
    }

    /**
     * 根据ID获取具体信息 type 信息类型 clazz 类
     */
    public static <T> T findBean(String type, String id, Class<T> clazz) {
    	Map map = ConfigMemory.get(type, clazz);
        if (map == null) {
        	map = new HashMap();
        	ConfigMemory.put(type, map);
        }
        T bean =  ConfigMemory.getBean(type, id, clazz);
        if(bean == null) {
        	try {
				  bean = clazz.newInstance();
				  map.put(id, bean);
			} catch (InstantiationException e) {
			} catch (IllegalAccessException e) {
			}
        }
        return bean;
    }

    /**
     * 根据ID模糊获取具体信息 type 信息类型 clazz 集合
     */
    public static <T> List<T> findBeans(String type, String id, Class<T> clazz) {
        synchronized (ConfigMemory.getAll()) {
            List<T> list = new LinkedList<T>();
            Map<String, T> map = ConfigMemory.get(type, clazz);
            for (String key : map.keySet()) {
                if (key.contains(id)) {
                    list.add(map.get(key));
                }
            }
            return list;
        }
    }

    /**
     * 加载配置数据到内存
     *
     * @throws
     */
    public static void loadAll() {
        String code = "";
        for (Model model : Model.values()) {
            try {
                code = model.getCode();
                File file = new File(CONFIG_PATH.get() + code + ".yaml");
                log.info("file path = " + file.getAbsolutePath());
                if (!file.exists()) {
                    log.info("配置数据[{}]不存在,加载失败", code);
                    continue;
                }
                Map<String, Object> map = YamlUtil.loadConfig(file);
                if (map != null) {
                    ConfigMemory.put(code, map);
                }
                log.info("配置数据[{}]加载成功", code);
            } catch (Exception e) {
                log.error("配置数据[" + code + "]加载异常", e);
            }
        }
    }

    /**
     * 一类信息
     *
     * @return
     */
    public static <T> List<T> findBeansByModel(Model model) {
        Map<String, T> map = ConfigService.find(model.getCode(),
                model.getClazz());
        if (map == null) {
            return null;
        }
        return new ArrayList<T>(map.values());
    }
}
